import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { BadRequestException, forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import Redis from 'ioredis';
import { isEmpty, isNil } from 'lodash';

import { EntityManager, In, IsNull, Like, Not, Repository } from 'typeorm';

import { BusinessException } from '~/common/exceptions/biz.exception';
import { ErrorEnum } from '~/constants/error-code.constant';
import { SYS_USER_INITPASSWORD } from '~/constants/system.constant';
import {
  genAuthPVKey,
  genAuthPermKey,
  genAuthTokenKey,
  genOnlineUserKey,
} from '~/helper/genRedisKey';

import { paginate } from '~/helper/paginate';
import { Pagination } from '~/helper/paginate/pagination';
import { standardPaginate } from '~/helper/paginate/standard-paginate';
import { StandardPagination } from '~/helper/paginate/standard-pagination';
import { AccountUpdateDto } from '~/modules/auth/dto/account.dto';

import { md5, randomValue } from '~/utils';

import { AccessTokenEntity } from '../auth/entities/access-token.entity';
import { ParamConfigService } from '../system/param-config/param-config.service';
import { RoleEntity } from '../system/role/role.entity';

import { UserStatus } from './constant';
import { PasswordUpdateDto } from './dto/password.dto';
import { UserDto, UserQueryDto, UserUpdateDto, UserNormalQueryDto } from './dto/user.dto';
import { UserEntity } from './user.entity';
import { UserAdminService } from './user-admin/user-admin.service';
import { UserWechatService } from './user-wechat/user-wechat.service';
import { TenantService } from '../tenant/tenant.service';
import { UserWechatEntity } from './user-wechat/user-wechat.entity';
import { TenantEntity } from '../tenant/tenant.entity';
import { PointsService } from '../points/points.service';
import { UserRole } from '../system/role/role.constant';
import { IUserInfoModel } from './user.model';
import { CommonStatus } from '~/common/entity/common.entity';
import { MpAuthUpdateUserInfoDto } from '../miniapp/auth/auth.dto';
import { CategoryDiseaseService } from '../category-disease/category-disease.service';
import { CategoryDiseaseEntity } from '../category-disease/category-disease.entity';

@Injectable()
export class UserService {
  private readonly logger = new Logger(UserService.name);

  constructor(
    @InjectRedis()
    private readonly redis: Redis,
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
    @InjectRepository(RoleEntity)
    private readonly roleRepository: Repository<RoleEntity>,
    @InjectEntityManager() private entityManager: EntityManager,
    private readonly paramConfigService: ParamConfigService,
    private readonly userAdminService: UserAdminService,
    private readonly userWechatService: UserWechatService,
    @Inject(forwardRef(() => TenantService))
    private readonly tenantService: TenantService,
    private readonly pointsService: PointsService,
		private readonly categoryDiseaseService: CategoryDiseaseService,
  ) {}

  async hasUser(id: number): Promise<boolean> {
    const user = await this.userRepository.findOneBy({ id });

    if (isNil(user)) {
      return false;
    }

    return true;
  }

  async findUserById(id: number): Promise<UserEntity | undefined> {
    return this.userRepository
      .createQueryBuilder('user')
      .where({
        id,
        status: UserStatus.Enabled,
      })
      .getOne();
  }

  async findUserByUserName(username: string): Promise<UserEntity | undefined> {
    return this.userRepository
      .createQueryBuilder('user')
      .where({
        username,
        status: UserStatus.Enabled,
      })
      .getOne();
  }

  /**
   * 获取用户信息
   * @param uid user id
   */
  async getAccountInfo(uid: number): Promise<Partial<IUserInfoModel>> {
    const user = await this.userRepository
      .createQueryBuilder('user')
      .leftJoinAndSelect('user.admin', 'admin')
      .leftJoin('user.wechat', 'wechat')
      .addSelect([
        'wechat.nickname',
        'wechat.avatar',
        'wechat.phone',
        'wechat.bmi',
        'wechat.bloodPressureSbp',
        'wechat.bloodPressureDbp',
        'wechat.fastingBloodGlucose',
        'wechat.ldlCholesterol',
        'wechat.uricAcid',
				'wechat.healthPoints',
      ])
      .leftJoin('user.tenant', 'tenant')
      .addSelect(['tenant.name', 'tenant.id', 'tenant.code'])
      .leftJoinAndSelect('user.role', 'role')
      .leftJoin('user.labels', 'labels')
      .addSelect(['labels.label', 'labels.value'])
      .where('user.id = :uid', { uid })
      .andWhere('user.status = :status', { status: UserStatus.Enabled })
      .getOne();

    if (!user) {
      throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
    }

    if (user.admin) {
      delete user.admin.password;
      delete user.admin.psalt;
    }

    const params: Partial<IUserInfoModel> = {
      ...user,
      ...(user?.wechat ?? {}),
      isAdmin: user?.role?.value === UserRole.ADMIN,
      isSuperAdmin: user?.role?.value === UserRole.SUPER_ADMIN,
    };

    delete params.wechat;

    const points = await this.pointsService.getPointsByUserId(user.id);

    params.knowledgePoints = points?.value ?? 0;

    return params;
  }

  /**
   * 更新个人信息
   */
  async updateAccountInfo(uid: number, info: AccountUpdateDto): Promise<void> {
    const user = await this.userRepository.findOneBy({ id: uid });
    if (isEmpty(user)) throw new BusinessException(ErrorEnum.USER_NOT_FOUND);

    const data = {
      ...(info.nickname ? { nickname: info.nickname } : null),
      ...(info.avatar ? { avatar: info.avatar } : null),
      ...(info.email ? { email: info.email } : null),
      ...(info.phone ? { phone: info.phone } : null),
      ...(info.qq ? { qq: info.qq } : null),
      ...(info.remark ? { remark: info.remark } : null),
    };

    // if (!info.avatar && info.qq) {
    //   // 如果qq不等于原qq，则更新qq头像
    //   if (info.qq !== user.qq) data.avatar = await this.qqService.getAvater(info.qq);
    // }

    await this.userRepository.update(uid, data);
  }

  /**
   * 更改密码
   */
  async updatePassword(uid: number, dto: PasswordUpdateDto): Promise<void> {
    const user = await this.userRepository.findOneBy({ id: uid });
    if (isEmpty(user)) throw new BusinessException(ErrorEnum.USER_NOT_FOUND);

    // const comparePassword = md5(`${dto.oldPassword}${user.psalt}`);
    // 原密码不一致，不允许更改
    // if (user.password !== comparePassword) throw new BusinessException(ErrorEnum.PASSWORD_MISMATCH);

    // const password = md5(`${dto.newPassword}${user.psalt}`);
    // await this.userRepository.update({id: uid}, {password});
    // await this.upgradePasswordV(user.id);
  }

  /**
   * 直接更改密码
   */
  async forceUpdatePassword(uid: number, password: string): Promise<void> {
    const user = await this.userRepository.findOneBy({ id: uid });

    // const newPassword = md5(`${password}${user.psalt}`);
    // await this.userRepository.update({id: uid}, {password: newPassword});
    // await this.upgradePasswordV(user.id);
  }

  /**
   * 增加系统用户，如果返回false则表示已存在该用户
   */
  async create({ username, password, role, ...data }: UserDto): Promise<void> {
    // const exists = await this.userRepository.findOneBy({
    //   username,
    // });
    // if (!isEmpty(exists)) throw new BusinessException(ErrorEnum.SYSTEM_USER_EXISTS);

    await this.entityManager.transaction(async (manager) => {
      const salt = randomValue(32);

      if (!password) {
        const initPassword = await this.paramConfigService.findValueByKey(SYS_USER_INITPASSWORD);
        password = md5(`${initPassword ?? '123456'}${salt}`);
      } else {
        password = md5(`${password ?? '123456'}${salt}`);
      }
      const u = manager.create(UserEntity, {
        // username,
        // password,
        ...data,
        // psalt: salt,
        // roles: await this.roleRepository.findBy({ id: In(roleIds) }),
        // dept: await DeptEntity.findOneBy({id: deptId}),
      });

      const result = await manager.save(u);
      return result;
    });
  }

  /**
   * 创建超级管理员
   */
  async createAdmin({ username, password, role, tenantId, ...data }: UserDto): Promise<UserEntity> {
    let tenant: TenantEntity = null;

    const userAdmin = await this.userAdminService.createBindTenant(username, password, tenantId);

    const userRole = await this.roleRepository.findOneBy({ id: role });

    if (tenantId) {
      tenant = await this.tenantService.getTenantById(tenantId);

      if (!tenant) {
        throw new BusinessException(ErrorEnum.NO_TENANT);
      }
    }

    const user: UserEntity = await this.userRepository.save({
      ...data,
      username,
      password,
      admin: userAdmin,
      role: userRole,
      tenant,
    });

    // 不返回 admin 和 role 信息
    delete user.admin;
    delete user.role;

    return user;
  }

  /**
   * 更新用户信息
   */
  async update(id: number, { password, role, status, ...data }: UserUpdateDto): Promise<void> {
    await this.entityManager.transaction(async (manager) => {
      if (password) await this.forceUpdatePassword(id, password);

      await manager.update(UserEntity, id, {
        ...data,
        status,
      });

      const user = await this.userRepository
        .createQueryBuilder('user')
        .leftJoinAndSelect('user.roles', 'roles')
        .leftJoinAndSelect('user.dept', 'dept')
        .where('user.id = :id', { id })
        .getOne();
      if (role) {
        await manager.createQueryBuilder().relation(UserEntity, 'roles').of(id);
        // .addAndRemove(roleIds, user.roles)
      }
      // if (deptId) {
      //   await manager.createQueryBuilder().relation(UserEntity, 'dept').of(id).set(deptId);
      // }

      if (status === 0) {
        // 禁用状态
        await this.forbidden(id);
      }
    });
  }

  /**
   * 查找用户信息
   * @param id 用户id
   */
  async info(id: number): Promise<UserEntity> {
    const user = await this.userRepository
      .createQueryBuilder('user')
      .leftJoinAndSelect('user.roles', 'roles')
      .leftJoinAndSelect('user.dept', 'dept')
      .where('user.id = :id', { id })
      .getOne();

    // delete user.password;
    // delete user.psalt;

    return user;
  }

  /**
   * 根据ID列表删除用户
   */
  async delete(userIds: number[]): Promise<void | never> {
    const rootUserId = await this.findRootUserId();
    if (userIds.includes(rootUserId)) throw new BadRequestException('不能删除root用户!');

    await this.userRepository.delete(userIds);
  }

  /**
   * 查找超管的用户ID
   */
  async findRootUserId(): Promise<any> {
    // const user = await this.userRepository.findOneBy({
    //   roles: { id: ROOT_ROLE_ID },
    // })
    // return user.id
  }

  /**
   * 查询用户列表
   */
  async list({
    page,
    pageSize,
    username,
    deptId,
    status,
  }: UserQueryDto): Promise<Pagination<UserEntity>> {
    const queryBuilder = this.userRepository
      .createQueryBuilder('user')
      .leftJoinAndSelect('user.dept', 'dept')
      .leftJoinAndSelect('user.roles', 'role')
      // .where('user.id NOT IN (:...ids)', { ids: [rootUserId, uid] })
      .where({
        ...(username ? { username: Like(`%${username}%`) } : null),
        // ...(nickname ? {nickname: Like(`%${nickname}%`)} : null),
        // ...(email ? {email: Like(`%${email}%`)} : null),
        ...(!isNil(status) ? { status } : null),
      });

    if (deptId) queryBuilder.andWhere('dept.id = :deptId', { deptId });

    return paginate<UserEntity>(queryBuilder, {
      page,
      pageSize,
    });
  }

  async listByTenant({ page, pageSize, tenantId }: UserQueryDto): Promise<Pagination<UserEntity>> {
    const queryBuilder = this.userRepository
      .createQueryBuilder('user')
      .leftJoinAndSelect('user.wechat', 'wechat')
      .where({
        tenant: { id: tenantId },
        status: CommonStatus.YES,
        admin: IsNull(),
      });

    return paginate<UserEntity>(queryBuilder, {
      page,
      pageSize,
    });
  }

	/**
	 * 获取普通用户列表
	 * @param
	 */
	async listUserNormal({ page, pageSize, nickname, phone, tenantId }: UserNormalQueryDto): Promise<StandardPagination<UserEntity>> {
		const queryBuilder = this.userRepository
			.createQueryBuilder('user')
			.leftJoinAndSelect('user.wechat', 'wechat')
			.leftJoinAndSelect('user.tenant', 'tenant') // 关联查询tenant
			.where('user.admin IS NULL') // 排除admin用户
			.andWhere('user.status = :status', { status: CommonStatus.YES });

		// 支持昵称的模糊查询
		if (nickname) {
			queryBuilder.andWhere('wechat.nickname LIKE :nickname', { nickname: `%${nickname}%` });
		}

		// 支持手机号的模糊查询
		if (phone) {
			queryBuilder.andWhere('wechat.phone LIKE :phone', { phone: `%${phone}%` });
		}

		// 支持按租户ID查询
		if (tenantId) {
			queryBuilder.andWhere('tenant.id = :tenantId', { tenantId });
		}

		// 按创建时间倒序排序
		queryBuilder.orderBy('user.createdAt', 'DESC');

		return standardPaginate<UserEntity>(queryBuilder, { page, pageSize });
	}

  /**
   * 禁用用户
   */
  async forbidden(uid: number, accessToken?: string): Promise<void> {
    await this.redis.del(genAuthPVKey(uid));
    await this.redis.del(genAuthTokenKey(uid));
    await this.redis.del(genAuthPermKey(uid));
    if (accessToken) {
      const token = await AccessTokenEntity.findOne({
        where: { value: accessToken },
      });
      this.redis.del(genOnlineUserKey(token.id));
    }
  }

  /**
   * 禁用多个用户
   */
  async multiForbidden(uids: number[]): Promise<void> {
    if (uids) {
      const pvs: string[] = [];
      const ts: string[] = [];
      const ps: string[] = [];
      uids.forEach((uid) => {
        pvs.push(genAuthPVKey(uid));
        ts.push(genAuthTokenKey(uid));
        ps.push(genAuthPermKey(uid));
      });
      await this.redis.del(pvs);
      await this.redis.del(ts);
      await this.redis.del(ps);
    }
  }

  /**
   * 升级用户版本密码
   */
  async upgradePasswordV(id: number): Promise<void> {
    // admin:passwordVersion:${param.id}
    const v = await this.redis.get(genAuthPVKey(id));
    if (!isEmpty(v)) await this.redis.set(genAuthPVKey(id), Number.parseInt(v) + 1);
  }

  /**
   * 判断用户名是否存在
   */
  async exist(username: string) {
    // const user = await this.userRepository.findOneBy({username});
    // if (isNil(user)) throw new BusinessException(ErrorEnum.SYSTEM_USER_EXISTS);

    return true;
  }

  /**
   * 注册
   */
  async register({ username, ...data }): Promise<void> {
    // const exists = await this.userRepository.findOneBy({
    //   username,
    // });
    // if (!isEmpty(exists)) throw new BusinessException(ErrorEnum.SYSTEM_USER_EXISTS);

    await this.entityManager.transaction(async (manager) => {
      const salt = randomValue(32);

      const password = md5(`${data.password ?? 'a123456'}${salt}`);

      // const u = manager.create(UserEntity, {
      // username,
      // password,
      // status: 1,
      // psalt: salt,
      // });

      // const user = await manager.save(u);

      // return user;
    });
  }

  /**
   * 通过openId判断当前用户是否存在
   * @param openid
   */
  async existByOpenid(openid: string): Promise<Boolean> {
    // const user: UserEntity = await this.userRepository.findOneBy({openid});
    // if (isNil(user)) throw new BusinessException(ErrorEnum.SYSTEM_USER_EXISTS);

    return true;
  }

  /**
   * 通过微信id获取用户信息
   * @param wid
   * @returns
   */
  async getUserByWechatId(wid: number): Promise<UserEntity> {
    return await this.userRepository.findOneBy({ wechat: { id: wid } });
  }

  /**
   * 查询当前的openid是否存在，不存在则创建
   * @param openid - 微信openid
   * @param data - 用户信息
   */
  async registerByOpenid(openid: string, tenantId: number): Promise<UserEntity> {
    if (!openid) {
      throw new BusinessException(ErrorEnum.INVALID_OPENID);
    }

    // 创建用户
    const wechatUser: UserWechatEntity = await this.userWechatService.getUserByOpenId(openid);

    if (!isEmpty(wechatUser)) {
      return await this.getUserByWechatId(wechatUser.id);
    }

    const tenant: TenantEntity = await this.tenantService.getTenantById(tenantId);

    if (isNil(tenant)) {
      throw new BusinessException(ErrorEnum.NO_TENANT);
    }

    const wechat: UserWechatEntity = await this.userWechatService.createUserByOpenId(openid);

    const user: UserEntity = await this.userRepository.save({
      wechat,
      tenant,
    });

    // 初始化积分
    await this.pointsService.getPointsByUserId(user.id);

    return user;
  }

  /**
   * 通过adminId获取用户信息
   * @param adminId
   */
  async getUserByAdminId(adminId: number): Promise<UserEntity> {
    return this.userRepository.findOneBy({ admin: { id: adminId } });
  }

  /**
   * 绑定用户角色
   */
  async bindRole(userId: number, role: RoleEntity): Promise<void> {
    const user = await this.userRepository.findOneBy({ id: userId });

    if (!user) {
      throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
    }

    await this.userRepository.update(userId, { role });
  }

  /**
   * 绑定管理员到租户
   */
  async bindAdminToTenant(userId: number, tenant: TenantEntity): Promise<void> {
    const user = await this.userRepository.findOneBy({ id: userId });

    if (!user) {
      throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
    }

    await this.userAdminService.bindAdminToTenant(user.admin.id, tenant);
  }

  async updateUserPhone(userId: number, phone: string): Promise<void> {
    const user = await this.userRepository.findOne({
      where: { id: userId },
      relations: ['wechat'],
    });

    if (!user || !user.wechat) {
      throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
    }

    await this.userWechatService.updateUserById(user?.wechat?.id, { phone });
  }

  async updateWechatUserInfo(uid: number, dto: MpAuthUpdateUserInfoDto) {
    const user = await this.userRepository.findOne({
      where: { id: uid },
      relations: ['wechat'],
    });

    if (isEmpty(user)) {
      throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
    }

    const params: Record<string, any> = {};

    if (dto?.nickname) {
      params.nickname = dto?.nickname;
    }

    if (dto?.avatar) {
      params.avatar = dto?.avatar;
    }

    // 添加健康数据字段
    if (dto?.healthPoints) {
      params.healthPoints = dto?.healthPoints ?? 0;
    }

    if (dto?.bmi) {
      params.bmi = dto?.bmi ?? 0;
    }

    if (dto?.bloodPressureSbp) {
      params.bloodPressureSbp = dto?.bloodPressureSbp ?? 0;
    }

    if (dto?.bloodPressureDbp) {
      params.bloodPressureDbp = dto?.bloodPressureDbp ?? 0;
    }

    if (dto?.fastingBloodGlucose) {
      params.fastingBloodGlucose = dto?.fastingBloodGlucose ?? 0;
    }

    if (dto?.ldlCholesterol) {
      params.ldlCholesterol = dto?.ldlCholesterol ?? 0;
    }

    if (dto?.uricAcid) {
      params.uricAcid = dto?.uricAcid ?? 0;
    }

    // 处理疾病ID
    if (dto?.diseaseId) {
      // params.disease_id = dto?.disease_id;
			await this.categoryDiseaseService.createOrUpdateUserDiseaseRelation(user.id, dto.diseaseId);
    }

    await this.userWechatService.updateUserById(user.wechat.id, params);
  }

	/**
	 * 获取用户的疾病分类ID
	 * @param uid 用户ID
	 * @returns 疾病分类ID或null
	 */
	async getUserDisease(uid: number): Promise<number | null> {
		if (!uid) {
			return null;
		}

		const diseaseId = await this.categoryDiseaseService.findCategoryIdByUserId(uid);

		return diseaseId;
	}

	/**
	 * 构建应用用户查询构建器
	 * @param keyword 关键词
	 * @param diseaseId 疾病分类ID
	 * @returns 查询构建器
	 */
	private buildAppUserQuery({
		keyword,
		diseaseId,
	}: {
		keyword?: string;
		diseaseId?: number;
	} = {}) {
		// 创建查询构建器，关联用户、微信信息和疾病分类信息
		const queryBuilder = this.userRepository
			.createQueryBuilder('user')
			.leftJoinAndSelect('user.wechat', 'wechat')
			.leftJoin('user.role', 'role')
			.where('(role.id = :roleId OR role.id IS NULL)', { roleId: 3 })
			.andWhere('user.status = :status', { status: UserStatus.Enabled });

		// 关键词搜索（匹配微信昵称或手机号）
		if (keyword) {
			queryBuilder.andWhere('(wechat.nickname LIKE :keyword OR wechat.phone LIKE :keyword)', {
				keyword: `%${keyword}%`
			});
		}

		// 按疾病分类ID筛选用户
		if (diseaseId) {
			queryBuilder.andWhere('user.id IN (' +
				'SELECT cd.user_id FROM ah_category_disease cd WHERE cd.category_id = :diseaseId' +
			')', { diseaseId });
		}

		// 按创建时间排序（最新注册的用户在前）
		queryBuilder.orderBy('user.createdAt', 'DESC');

		return queryBuilder;
	}

	/**
	 * 为用户列表添加疾病信息
	 * @param users 用户列表
	 * @returns 包含疾病信息的用户列表
	 */
	private async enrichUsersWithDisease(users: any[]): Promise<any[]> {
		const usersWithDisease: any[] = [];

		if (users && users.length > 0) {
			for (const user of users) {
				// 获取用户的疾病分类信息
				const diseaseRelation = await this.categoryDiseaseService.findCategoryIdByUserId(user.id);
				let diseaseInfo = null;

				if (diseaseRelation) {
					// 获取完整的疾病分类信息
					const category = await this.entityManager
						.createQueryBuilder()
						.select(['category.id', 'category.name', 'category.code'])
						.from('ah_category', 'category')
						.where('category.id = :categoryId', { categoryId: diseaseRelation })
						.getRawOne();

					diseaseInfo = {
						id: category?.category_id || null,
						name: category?.category_name || null,
						code: category?.category_code || null,
					};
				}

				usersWithDisease.push({
					...user,
					disease: diseaseInfo,
				});
			}
		}

		return usersWithDisease;
	}

	/**
	 * 获取应用用户列表
	 * @param page 页码
	 * @param pageSize 每页大小
	 * @param keyword 关键词
	 * @param diseaseId 疾病分类ID
	 * @returns 用户列表
	 */
	async getAppUserByPage({
		page = 1,
		pageSize = 10,
		keyword,
		diseaseId,
	}: {
		page?: number;
		pageSize?: number;
		keyword?: string;
		diseaseId?: number;
	}): Promise<StandardPagination<any>> {
		// 构建查询
		const queryBuilder = this.buildAppUserQuery({ keyword, diseaseId });

		// 获取分页结果
		const result = await standardPaginate(queryBuilder, { page, pageSize });

		// 为用户添加疾病信息
		const usersWithDisease = await this.enrichUsersWithDisease(result.data || []);

		return {
			...result,
			data: usersWithDisease,
		};
	}

	/**
	 * 获取全部应用用户（不分页）
	 * @param keyword 关键词
	 * @param diseaseId 疾病分类ID
	 * @returns 用户列表
	 */
	async getAllAppUsers({
		keyword,
		diseaseId,
	}: {
		keyword?: string;
		diseaseId?: number;
	} = {}): Promise<any[]> {
		// 构建查询
		const queryBuilder = this.buildAppUserQuery({ keyword, diseaseId });

		// 获取所有结果
		const users = await queryBuilder.getMany();

		// 为用户添加疾病信息
		return await this.enrichUsersWithDisease(users);
	}

	/**
	 * 判断租户是否存在用户
	 * @param tenantId 租户ID
	 * @returns 是否存在用户
	 */
	async hasUserBindTenant(tenantId: number): Promise<boolean> {
		const user = await this.userRepository.findOne({
			where: {
				tenant: { id: tenantId },
				admin: { id: IsNull() },
			},
		});

		return !isEmpty(user);
	}

	async switchTenant(userId: number, tenantId: number): Promise<void> {
		const user = await this.userRepository.findOne({
			where: { id: userId },
		});

		if (!user) {
			throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
		}

		const tenant = await this.tenantService.getTenantById(tenantId);

		if (!tenant) {
			throw new BusinessException(ErrorEnum.NO_TENANT);
		}

		await this.userRepository.update(userId, { tenant });
	}
}
